/*
 * BatchProcess.java
 *
 * Created on March 28, 2007, 11:01 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.jjenkins.data;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.swing.JOptionPane;

/**
 * to do all the batch stuff
 * @author Rick Allison
 */
public class BatchProcess {
    
    private static BatchProcess instance = null;
    
    /**
     * singleton pattern
     * @return instance
     */
    public static synchronized BatchProcess getInstance() {
        if (instance == null) {
            instance = new BatchProcess();
        }
        return instance;
    }
    
    /** Creates a new instance of BatchProcess */
    private BatchProcess() {
    }
    
    
    /**
     * For this method do i go through all stores, or just the store where they click the button??
     *
     * what this does is go through all the items and compare the items on hand +items on order to the reorder point.
     * if it is lower then reorder, i need to order the reorder amount.
     *
     * to do the actual orders, i need to get the get the product id, then go through through the vendor-product table
     * and find the vendor that has the lowest price for that item.  then make an order to that vendor for the reorder amount
     * @throws edu.byu.isys413.jjenkins.data.DataException formatting
     */
    public void orderInventory() throws DataException{
        System.out.println("really ordering inventory now");
        StoreBO store = StoreDAO.getInstance().read("sto1");
        //i'll just do one store for now, then i can easily loop it for all stores.'
        List listOfProducts = StoreDAO.getInstance().getAllProductsByStore(store.getId());
        //now i have all the products for a particular store, so i go through all products and see which need to be orderd
        List productsToOrder = StoreProductDAO.getInstance().getProductsToOrder(listOfProducts);
        //so now i have all the products i need to orde, so for each product i need to find the cheapest price, and place an order
        //to that vendor for the reorder amount.
        generateOrders(productsToOrder);
        
    }//
    
    /**
     * this method takes a list of items to order, and makes the order for all of the items
     * @param productsToOrder list of products to order
     */
    public void generateOrders(List productsToOrder) {
        for(int i=0;i<productsToOrder.size();i++){
            StoreProductBO prod = (StoreProductBO) productsToOrder.get(i);
            VendorProductBO cheap = new VendorProductBO();
            try {
                cheap = VendorProductDAO.getInstance().findCheapest(prod.getId());
            } catch (ConnectionPoolException ex) {
                ex.printStackTrace();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            OrderBO order;
            try {
                order = OrderDAO.getInstance().create();
                order.setProduct_id(prod.getId());
                order.setVendor_id(cheap.getId());
                order.setQuantity(prod.getReorderPoint());
                order.setUnit_price((int)cheap.getPrice());
                prod.setQtyOnOrder(order.getQuantity());//this updates the inventory levels
                System.out.println("Making order line to vendor "+cheap.getVendorId()+" for product "+cheap.getProductId()+" at "+cheap.getPrice());
            } catch (DataException ex) {
                ex.printStackTrace();
            }
        }//for
    }
    
    /**
     *
     * @throws edu.byu.isys413.jjenkins.data.DataException
     */
    public void processMaxDaysOverdue()throws DataException{
        int numOverdue = 0;
        Date currentDate = new Date(System.currentTimeMillis());
        try{
            List list = ((ForRentDAO)ForRentDAO.getInstance()).readAll();
            for(int i = 0; i < list.size(); i++){
                if(((ForRentBO)list.get(i)).getCurrentRentalID() != null){
                    PhysicalBO phys = (PhysicalBO)PhysicalDAO.getInstance().read(((ForRentBO)list.get(i)).getId());
                    if(phys.getType().equalsIgnoreCase("rent")){
                        int daysOverdue = ((ForRentBO)list.get(i)).getCurrentRental().calcDaysOverdueBatch();
                        String conceptualID = ((PhysicalBO)PhysicalDAO.getInstance().read(((ForRentBO)list.get(i)).getId())).getConceptual().getId();
                        int maxDaysOverdue = ((ConceptualRentalBO)ConceptualRentalDAO.getInstance().read(conceptualID)).getMaxDaysOverdue();
                        double replacementPrice = ((ConceptualRentalBO)ConceptualRentalDAO.getInstance().read(conceptualID)).getReplacementPrice();
                        if(daysOverdue >= maxDaysOverdue){
                            numOverdue++;
                            phys.setType("sale");
                            PhysicalDAO.getInstance().save(phys);
                            
                          
                            ForSaleBO forSale = (ForSaleBO)ForSaleDAO.getInstance().create();
                            forSale.setId(phys.getId());
                            forSale.setNewOrUsed(0);
                            
                            phys.setType("sale");
                            
                            TransactionBO trans = TransactionDAO.getInstance().create();
                            SaleBO sale = (SaleBO)((SaleDAO)RevenueSourceFactory.getInstance().getDAO("sale")).create();
                            sale.setProd_id(((ForRentBO)list.get(i)).getId());
                            sale.setQuantity(1);
                            sale.setPrice(replacementPrice);
                            sale.setType("sale");
                            sale.setRs_id(sale.getId());
                            sale.setForSale(forSale);
                            sale.createDescription();
                            SaleDAO.getInstance().save(sale);
                            
                            TransactionLineBO line = TransactionLineDAO.getInstance().create();
                            line.setRevenueSource(sale);
                            line.setTransaction(trans);
                            trans.setType("Sale");
                            trans.setDate(new Date(System.currentTimeMillis()));
                            trans.setStatus("pending");
                            trans.addTransactionLine(line);
                            CustomerBO cust = ((ForRentBO)list.get(i)).getCurrentRental().getLine().getTransaction().getCustomer();
                            trans.setCustomer(cust);
                            PaymentBO pay = PaymentDAO.getInstance().create();
                            
                            trans.setCurrentOpts(CurrentOptsDAO.getInstance().read("curr1"));
                            trans.endTransaction();
                            double total = trans.getTotal();
                            pay.setAmount(total);
                            pay.setType("credit");
                            trans.setPayment(pay);
                            trans.display();
                            pay.setTransaction(trans);
                            
                            TransactionDAO.getInstance().save(trans);
                            PaymentDAO.getInstance().save(pay);
                        }
                    }//end inner if
                }//end if
            }//end for
            JOptionPane.showMessageDialog(null, "Max Days Overdue processing completed successfully\n" + numOverdue + " rental items were found to be overdue.");
        }catch (SQLException e){
            e.printStackTrace();
        }
        
    }
    
    /**
     *
     * @throws edu.byu.isys413.jjenkins.data.DataException
     */
    public void processMaxTimesRented()throws DataException{
        try{
            ConnectionPool connPool = ConnectionPool.getInstance();
            Connection conn = connPool.get();
            ForRentBO object = null;
            
            PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM for_rent WHERE product_id IN(SELECT product_id FROM physical WHERE conceptual_id IN(SELECT product_id FROM conceptual_rental WHERE for_rent.times_rented >= conceptual_rental.max_times_rented))");
            pstmt.execute();
            ResultSet rs = pstmt.getResultSet();
            
            while (rs.next()) {
                if(rs.getString("current_rental_id") == null){ //&& rs.getString("type").equalsIgnoreCase("rental")
                    object = new ForRentBO();
                    PreparedStatement pstmt2 = conn.prepareStatement("SELECT product_type FROM physical WHERE product_id = ?");
                    pstmt2.setString(1, rs.getString("product_id"));
                    pstmt2.execute();
                    ResultSet rs2 = pstmt2.getResultSet();
                    
                    if(rs2.next()){
                        if(rs2.getString("product_type").equalsIgnoreCase("rent")){
                            object.setId(rs.getString("product_id"));
                            PhysicalBO phys = (PhysicalBO)PhysicalDAO.getInstance().read(rs.getString("product_id"));
                            phys.setType("sale");
                            object.setTimesRented(rs.getInt("times_rented"));
                            object.setCurrentRentalID(rs.getString("current_rental_id"));
                            
                            object.setObjectAlreadyInDB(true);
                            ((ForRentDAO)ForRentDAO.getInstance()).save(object);
                            
                            ConceptualBO conc = ConceptualDAO.getInstance().create();
                            conc.setId(object.getId());
                            conc.setCategoryID("category_id1");
                            conc.setWarrantyID("warranty_id1");
                            conc.setManufacturer("manufacturer_id1");
                            conc.setObjectAlreadyInDB(true);
                            
                            ForSaleBO sale = (ForSaleBO)ForSaleDAO.getInstance().create();//(ForSaleBO)((ForSaleDAO)RevenueSourceFactory.getInstance().getDAO("sale")).create();
                            sale.setId(object.getId());
                            sale.setNewOrUsed(1);
                            sale.setType("sale");
                            sale.setStore(StoreDAO.getInstance().read("sto1"));
                            sale.setConceptual(conc);
                            String desc = ((PhysicalBO)PhysicalDAO.getInstance().read(object.getId())).getConceptual().getDescription();
                            String p = JOptionPane.showInputDialog("Enter the price for " + desc);
                            double price = Double.parseDouble(p);
                            sale.setPrice(price);
                            conc.setPrice(price);
                            ConceptualDAO.getInstance().save(conc);
                            sale.setObjectAlreadyInDB(true);
                            ForSaleDAO.getInstance().save(sale);
                            phys.setObjectAlreadyInDB(true);
                            PhysicalDAO.getInstance().save(phys,conn);
                        }
                    }//inner if
                }//outer if
            }//while
            
            conn.commit();
            connPool.release(conn);
            
            JOptionPane.showMessageDialog(null, "Max Times Rented processing completed successfully");
        }catch(SQLException e){
            e.printStackTrace();
        }catch(ConnectionPoolException e){
            e.printStackTrace();
        }
    }
}
